package io.renren.modules.car.service.impl;

import io.renren.common.entity.CarTypeEntity;
import io.renren.common.utils.*;
import io.renren.modules.car.dao.CarTypeRelationDao;
import io.renren.modules.car.entity.CarRelateDictReq;
import io.renren.modules.car.entity.DictRelationEntity;
import io.renren.modules.car.entity.req.CarDeleteReq;
import io.renren.modules.car.entity.req.CarSaveReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import io.renren.modules.car.dao.CarDao;
import io.renren.modules.car.entity.CarEntity;
import io.renren.modules.car.service.CarService;
import org.springframework.transaction.annotation.Transactional;


@Slf4j
@Service("carService")
public class CarServiceImpl extends ServiceImpl<CarDao, CarEntity> implements CarService {
    
    private final CarTypeRelationDao carTypeRelationDao;
    
    @Autowired
    public CarServiceImpl(CarTypeRelationDao carTypeRelationDao) {
        this.carTypeRelationDao = carTypeRelationDao;
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CarEntity> page = this.page(
                new Query<CarEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }
    
    /**
     * 根据用户id返回对应车辆的列表
     * @author zyzhao
     * @date 2022/4/17 14:44
     * @param userId
     * @return java.util.List<io.renren.modules.car.entity.CarEntity>
     */
    @Override
    public List<CarEntity> queryCarListByUserId(String userId) {
        QueryWrapper<CarEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        List<CarEntity> carEntities = list(queryWrapper);
        carEntities.forEach(car -> {
            List<String> typeLists = carTypeRelationDao.selectDictListByCarId(car.getCarId());
            String typeTrans = typeLists.stream().map(TransUtils::getCarTypeTrans).collect(Collectors.joining(","));
            car.setCarDict(StringUtils.join(typeLists, ","));
            car.setCarDictTrans(typeTrans);
            car.setCarTypeTrans(TransUtils.getCarTypeTrans(car.getCarType()));
        });
        return carEntities;
    }
    
    /**
     * 根据车辆id返回车辆信息
     * @author zyzhao
     * @date 2022/4/17 14:45
     * @param carId
     * @return io.renren.modules.car.entity.CarEntity
     */
    @Override
    public R queryCarInfoByCarId(Integer carId) {
        CarEntity car = getById(carId);
        if (null == car){
            log.error("根据id[ {} ]查询到的车辆为空", carId);
            return R.error(HttpStatus.SC_BAD_REQUEST, "该id对应车辆不存在");
        }
        // 匹配车型
        car.setCarTypeTrans(TransUtils.getCarTypeTrans(car.getCarType()));
        // 匹配车辆标签
        List<String> typeLists = carTypeRelationDao.selectDictListByCarId(carId);
        String typeTrans = typeLists.stream().map(TransUtils::getCarTypeTrans).collect(Collectors.joining(","));
        car.setCarDict(StringUtils.join(typeLists, ","));
        car.setCarDictTrans(typeTrans);
        
        return R.success(car);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveCar(CarSaveReq req) {
        
        CarEntity car = new CarEntity();
        BeanUtils.copyProperties(req, car);
        //car.setUserId(req.getUserId());
        save(car);
        Integer carId = car.getCarId();
        saveCarDict(req.getCarDict(), carId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R updateCar(CarSaveReq req) {
        CarEntity car = new CarEntity();
        BeanUtils.copyProperties(req, car);
        //car.setUserId(req.getUserId());
        boolean b = updateById(car);
        if (!b){
            log.error("该carId[{}]对应信息不存在或更新失败", req.getCarId());
            return R.error(HttpStatus.SC_BAD_REQUEST, "该carId对应信息不存在或更新失败");
        }
        carTypeRelationDao.deleteDictByCarId(car.getCarId());
        saveCarDict(req.getCarDict(), car.getCarId());
        
        return R.ok();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeCar(CarDeleteReq req) {
        removeByIds(req.getCarLists());
        carTypeRelationDao.deleteByCarIds(req.getCarLists());
    }
    
    @Override
    public R getDictListByPid(String pid) {
        // pid 传-1的时候，查全量的标签
        Map<String, List<CarTypeEntity>> allTypes = new LinkedHashMap<>();
        if ("-1".equals(pid)){
            List<CarTypeEntity> rootList = TransUtils.getCarTypeDictByPid("0");
            for (CarTypeEntity root : rootList) {
                allTypes.put(root.getDesc(), TransUtils.getCarTypeDictByPid(root.getId()));
            }
            return R.success(allTypes);
        }
        return R.success(TransUtils.getCarTypeDictByPid(pid));
    }
    
    @Override
    public R relateDict(CarRelateDictReq req) {
        CarEntity car = getById(req.getCarId());
        if (ObjectUtils.isEmpty(car)){
            return R.error("该车辆不存在");
        }
    
    
        carTypeRelationDao.deleteDictByCarId(car.getCarId());
        saveCarDict(String.join(",", req.getDictIds()), car.getCarId());
        return R.success("更新成功");
    }
    
    /**
     * 批量入库车辆标签信息
     * @author zyzhao
     * @date 2022/4/17 16:34
     * @param carDict 要入库的标签
     * @param carId 车辆id
     */
    private void saveCarDict(String carDict, Integer carId) {
        List<DictRelationEntity> dicts = new ArrayList<>();
        for (String dict : carDict.split(",")) {
            DictRelationEntity dictEntity = new DictRelationEntity();
            dictEntity.setCarId(carId);
            dictEntity.setDictId(dict);
            dicts.add(dictEntity);
        }
        dicts.forEach(carTypeRelationDao::insert);
    }
    
}